package com.xjtu.chapter08.thread.read_write;

import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author yjq
 * @version 1.0
 * @date 2021/8/31 22:04
 */
//通过定义一个读写锁ReentrantReadWriteLock来实现多个读者线程和多个写者线程访问共享数据，
// 读者和写者分别采用readLock)和writeLock()来加锁和释放锁。
public class RearAndWrite {

    public static void main(String[] args) {
        readWirteOp one = new readWirteOp();
        for (int i = 0; i <3 ; i++) {
            readThread readThread = new readThread(one);
            writeThread writeThread = new writeThread(one);
            readThread.start();
            writeThread.start();
        }
    }
}
class readThread extends Thread{
    readWirteOp rw;

    public readThread(readWirteOp rw) {
        this.rw = rw;
    }

    @Override
    public void run() {
        while (true){
            rw.reader();
        }
    }
}
class writeThread extends Thread{
    readWirteOp rw;

    public writeThread(readWirteOp rw) {
        this.rw = rw;
    }

    @Override
    public void run() {
        while (true){
            rw.writer(new Random().nextInt(1000));//随机写入一个数
        }
    }
}
//对共享数据进行读写操作的类
class readWirteOp{
    private int num;//共享数据
    private ReentrantReadWriteLock rw1 = new ReentrantReadWriteLock();//创建读写锁
    public void reader(){
        rw1.readLock().lock();//加读锁
        System.out.println(Thread.currentThread().getName()+" is ready to read number");
        try {
            Thread.sleep((long)(Math.random()*1000));//稍作停顿
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+ " have read number: "+num);
        rw1.readLock().unlock();//释放读锁
    }
    public void writer(int data){
        rw1.writeLock().lock();//加写锁
        System.out.println(Thread.currentThread().getName()+" is ready to write number");
        try {
            Thread.sleep((long)(Math.random()*1000));//稍作停顿
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.num = data;
        System.out.println(Thread.currentThread().getName()+"have written number: "+num);
        rw1.writeLock().unlock();//释放写锁
    }
}
